/******************************************************************************
 * Copyright (c) 1998 Lawrence Livermore National Security, LLC and other
 * HYPRE Project Developers. See the top-level COPYRIGHT file for details.
 *
 * SPDX-License-Identifier: (Apache-2.0 OR MIT)
 ******************************************************************************/

/* csr_filter.c */
HYPRE_Int hypre_CSRMatrixTruncateDiag(hypre_CSRMatrix *A);

/* csr_matop.c */
HYPRE_Int hypre_CSRMatrixAddFirstPass ( HYPRE_Int firstrow, HYPRE_Int lastrow, HYPRE_Int *marker,
                                        HYPRE_Int *twspace, HYPRE_Int *map_A2C, HYPRE_Int *map_B2C,
                                        hypre_CSRMatrix *A, hypre_CSRMatrix *B,
                                        HYPRE_Int nnzrows_C, HYPRE_Int nrows_C, HYPRE_Int ncols_C,
                                        HYPRE_Int *rownnz_C,
                                        HYPRE_MemoryLocation memory_location_C,
                                        HYPRE_Int *C_i, hypre_CSRMatrix **C_ptr );
HYPRE_Int hypre_CSRMatrixAddSecondPass ( HYPRE_Int firstrow, HYPRE_Int lastrow, HYPRE_Int *marker,
                                         HYPRE_Int *map_A2C, HYPRE_Int *map_B2C,
                                         HYPRE_Int *rownnz_C, HYPRE_Complex alpha,
                                         HYPRE_Complex beta, hypre_CSRMatrix *A,
                                         hypre_CSRMatrix *B, hypre_CSRMatrix *C);
hypre_CSRMatrix *hypre_CSRMatrixAddHost ( HYPRE_Complex alpha, hypre_CSRMatrix *A,
                                          HYPRE_Complex beta, hypre_CSRMatrix *B );
hypre_CSRMatrix *hypre_CSRMatrixAdd ( HYPRE_Complex alpha, hypre_CSRMatrix *A, HYPRE_Complex beta,
                                      hypre_CSRMatrix *B );
hypre_CSRMatrix *hypre_CSRMatrixBigAdd ( hypre_CSRMatrix *A, hypre_CSRMatrix *B );
hypre_CSRMatrix *hypre_CSRMatrixMultiplyHost ( hypre_CSRMatrix *A, hypre_CSRMatrix *B );
hypre_CSRMatrix *hypre_CSRMatrixMultiply ( hypre_CSRMatrix *A, hypre_CSRMatrix *B );
hypre_CSRMatrix *hypre_CSRMatrixDeleteZeros ( hypre_CSRMatrix *A, HYPRE_Real tol );
HYPRE_Int hypre_CSRMatrixTransposeHost ( hypre_CSRMatrix *A, hypre_CSRMatrix **AT, HYPRE_Int data );
HYPRE_Int hypre_CSRMatrixTranspose ( hypre_CSRMatrix *A, hypre_CSRMatrix **AT, HYPRE_Int data );
HYPRE_Int hypre_CSRMatrixReorder ( hypre_CSRMatrix *A );
HYPRE_Complex hypre_CSRMatrixSumElts ( hypre_CSRMatrix *A );
HYPRE_Real hypre_CSRMatrixFnorm( hypre_CSRMatrix *A );
HYPRE_Int hypre_CSRMatrixSplit(hypre_CSRMatrix *Bs_ext, HYPRE_BigInt first_col_diag_B,
                               HYPRE_BigInt last_col_diag_B, HYPRE_Int num_cols_offd_B, HYPRE_BigInt *col_map_offd_B,
                               HYPRE_Int *num_cols_offd_C_ptr, HYPRE_BigInt **col_map_offd_C_ptr, hypre_CSRMatrix **Bext_diag_ptr,
                               hypre_CSRMatrix **Bext_offd_ptr);
hypre_CSRMatrix * hypre_CSRMatrixAddPartial( hypre_CSRMatrix *A, hypre_CSRMatrix *B,
                                             HYPRE_Int *row_nums);
HYPRE_Int hypre_CSRMatrixComputeRowSum( hypre_CSRMatrix *A, HYPRE_Int *CF_i, HYPRE_Int *CF_j,
                                        HYPRE_Complex *row_sum, HYPRE_Int type, HYPRE_Complex scal,
                                        const char *set_or_add);
HYPRE_Int hypre_CSRMatrixComputeColSum( hypre_CSRMatrix *A, HYPRE_Complex *col_sum,
                                        HYPRE_Int type, HYPRE_Complex scal );
HYPRE_Int hypre_CSRMatrixExtractDiagonal( hypre_CSRMatrix *A, HYPRE_Complex *d, HYPRE_Int type);
HYPRE_Int hypre_CSRMatrixExtractDiagonalHost( hypre_CSRMatrix *A, HYPRE_Complex *d, HYPRE_Int type);
HYPRE_Int hypre_CSRMatrixScale(hypre_CSRMatrix *A, HYPRE_Complex scalar);
HYPRE_Int hypre_CSRMatrixSetConstantValues( hypre_CSRMatrix *A, HYPRE_Complex value);
HYPRE_Int hypre_CSRMatrixDiagScale( hypre_CSRMatrix *A, hypre_Vector *ld, hypre_Vector *rd);
HYPRE_Int hypre_CSRMatrixTaggedFnorm( hypre_CSRMatrix *A, HYPRE_Int num_tags, HYPRE_Int *tags,
                                      HYPRE_Real **tnorms_ptr );

/* csr_matop_device.c */
hypre_CSRMatrix *hypre_CSRMatrixAddDevice ( HYPRE_Complex alpha, hypre_CSRMatrix *A,
                                            HYPRE_Complex beta, hypre_CSRMatrix *B );
hypre_CSRMatrix *hypre_CSRMatrixMultiplyDevice ( hypre_CSRMatrix *A, hypre_CSRMatrix *B );
hypre_CSRMatrix *hypre_CSRMatrixTripleMultiplyDevice ( hypre_CSRMatrix *A, hypre_CSRMatrix *B,
                                                       hypre_CSRMatrix *C );
hypre_CSRMatrix *hypre_CSRMatrixDeleteZerosDevice ( hypre_CSRMatrix *A, HYPRE_Real tol );
HYPRE_Int hypre_CSRMatrixMergeColMapOffd( HYPRE_Int num_cols_offd_B, HYPRE_BigInt *col_map_offd_B,
                                          HYPRE_Int B_ext_offd_nnz, HYPRE_BigInt *B_ext_offd_bigj, HYPRE_Int *num_cols_offd_C_ptr,
                                          HYPRE_BigInt **col_map_offd_C_ptr, HYPRE_Int **map_B_to_C_ptr );
HYPRE_Int hypre_CSRMatrixSplitDevice_core( HYPRE_Int job, HYPRE_Int num_rows, HYPRE_Int B_ext_nnz,
                                           HYPRE_Int *B_ext_ii, HYPRE_BigInt *B_ext_bigj, HYPRE_Complex *B_ext_data, char *B_ext_xata,
                                           HYPRE_BigInt first_col_diag_B, HYPRE_BigInt last_col_diag_B, HYPRE_Int num_cols_offd_B,
                                           HYPRE_BigInt *col_map_offd_B, HYPRE_Int **map_B_to_C_ptr, HYPRE_Int *num_cols_offd_C_ptr,
                                           HYPRE_BigInt **col_map_offd_C_ptr, HYPRE_Int *B_ext_diag_nnz_ptr, HYPRE_Int *B_ext_diag_ii,
                                           HYPRE_Int *B_ext_diag_j, HYPRE_Complex *B_ext_diag_data, char *B_ext_diag_xata,
                                           HYPRE_Int *B_ext_offd_nnz_ptr, HYPRE_Int *B_ext_offd_ii, HYPRE_Int *B_ext_offd_j,
                                           HYPRE_Complex *B_ext_offd_data, char *B_ext_offd_xata );
HYPRE_Int hypre_CSRMatrixSplitDevice(hypre_CSRMatrix *B_ext, HYPRE_BigInt first_col_diag_B,
                                     HYPRE_BigInt last_col_diag_B, HYPRE_Int num_cols_offd_B, HYPRE_BigInt *col_map_offd_B,
                                     HYPRE_Int **map_B_to_C_ptr, HYPRE_Int *num_cols_offd_C_ptr, HYPRE_BigInt **col_map_offd_C_ptr,
                                     hypre_CSRMatrix **B_ext_diag_ptr, hypre_CSRMatrix **B_ext_offd_ptr);
HYPRE_Int hypre_CSRMatrixSetRownnzDevice( hypre_CSRMatrix *A );
HYPRE_Int hypre_CSRMatrixTransposeDevice ( hypre_CSRMatrix *A, hypre_CSRMatrix **AT,
                                           HYPRE_Int data );
hypre_CSRMatrix* hypre_CSRMatrixAddPartialDevice( hypre_CSRMatrix *A, hypre_CSRMatrix *B,
                                                  HYPRE_Int *row_nums);
HYPRE_Int hypre_CSRMatrixColNNzRealDevice( hypre_CSRMatrix *A, HYPRE_Real *colnnz);
HYPRE_Int hypre_CSRMatrixMoveDiagFirstDevice( hypre_CSRMatrix  *A );
HYPRE_Int hypre_CSRMatrixCheckDiagFirstDevice( hypre_CSRMatrix  *A );
HYPRE_Int hypre_CSRMatrixCheckForMissingDiagonal( hypre_CSRMatrix *A );
HYPRE_Int hypre_CSRMatrixReplaceDiagDevice( hypre_CSRMatrix *A, HYPRE_Complex *new_diag,
                                            HYPRE_Complex v, HYPRE_Real tol );
HYPRE_Int hypre_CSRMatrixComputeRowSumDevice( hypre_CSRMatrix *A, HYPRE_Int *CF_i, HYPRE_Int *CF_j,
                                              HYPRE_Complex *row_sum, HYPRE_Int type,
                                              HYPRE_Complex scal, const char *set_or_add );
HYPRE_Int hypre_CSRMatrixComputeColSumDevice( hypre_CSRMatrix *A,  HYPRE_Complex *col_sum,
                                              HYPRE_Int type, HYPRE_Complex scal );
HYPRE_Int hypre_CSRMatrixTaggedFnormDevice(hypre_CSRMatrix *A, HYPRE_Int num_tags,
                                           HYPRE_Int *tags, HYPRE_Real *tnorms);
HYPRE_Int hypre_CSRMatrixExtractDiagonalDevice( hypre_CSRMatrix *A, HYPRE_Complex *d,
                                                HYPRE_Int type );
hypre_CSRMatrix* hypre_CSRMatrixStack2Device(hypre_CSRMatrix *A, hypre_CSRMatrix *B);
hypre_CSRMatrix* hypre_CSRMatrixIdentityDevice(HYPRE_Int n, HYPRE_Complex alp);
hypre_CSRMatrix* hypre_CSRMatrixDiagMatrixFromVectorDevice(HYPRE_Int n, HYPRE_Complex *v);
hypre_CSRMatrix* hypre_CSRMatrixDiagMatrixFromMatrixDevice(hypre_CSRMatrix *A, HYPRE_Int type);
HYPRE_Int hypre_CSRMatrixRemoveDiagonalDevice(hypre_CSRMatrix *A);
HYPRE_Int hypre_CSRMatrixDropSmallEntriesDevice( hypre_CSRMatrix *A, HYPRE_Real tol,
                                                 HYPRE_Real *elmt_tols);
HYPRE_Int hypre_CSRMatrixPermuteDevice( hypre_CSRMatrix *A, HYPRE_Int *perm,
                                        HYPRE_Int *rqperm, hypre_CSRMatrix *B );
HYPRE_Int hypre_CSRMatrixSortRow(hypre_CSRMatrix *A);
HYPRE_Int hypre_CSRMatrixSortRowOutOfPlace(hypre_CSRMatrix *A);
HYPRE_Int hypre_CSRMatrixTriLowerUpperSolveDevice_core(char uplo, HYPRE_Int unit_diag,
                                                       hypre_CSRMatrix *A, HYPRE_Real *l1_norms, hypre_Vector *f, HYPRE_Int offset_f, hypre_Vector *u,
                                                       HYPRE_Int offset_u);
HYPRE_Int hypre_CSRMatrixTriLowerUpperSolveDevice(char uplo, HYPRE_Int unit_diag,
                                                  hypre_CSRMatrix *A, HYPRE_Real *l1_norms, hypre_Vector *f, hypre_Vector *u );
HYPRE_Int hypre_CSRMatrixTriLowerUpperSolveRocsparse(char uplo, HYPRE_Int unit_diag,
                                                     hypre_CSRMatrix *A, HYPRE_Real *l1_norms, HYPRE_Complex *f, HYPRE_Complex *u );
HYPRE_Int hypre_CSRMatrixTriLowerUpperSolveCusparse(char uplo, HYPRE_Int unit_diag,
                                                    hypre_CSRMatrix *A, HYPRE_Real *l1_norms, HYPRE_Complex *f, HYPRE_Complex *u );
HYPRE_Int hypre_CSRMatrixTriLowerUpperSolveOnemklsparse(char uplo, HYPRE_Int unit_diag,
                                                        hypre_CSRMatrix *A, HYPRE_Real *l1_norms, HYPRE_Complex *f, HYPRE_Complex *u );
HYPRE_Int hypre_CSRMatrixIntersectPattern(hypre_CSRMatrix *A, hypre_CSRMatrix *B, HYPRE_Int *markA,
                                          HYPRE_Int diag_option);
HYPRE_Int hypre_CSRMatrixDiagScaleDevice( hypre_CSRMatrix *A, hypre_Vector *ld, hypre_Vector *rd);
HYPRE_Int hypre_CSRMatrixCompressColumnsDevice(hypre_CSRMatrix *A, HYPRE_BigInt *col_map,
                                               HYPRE_Int **col_idx_new_ptr, HYPRE_BigInt **col_map_new_ptr);
HYPRE_Int hypre_CSRMatrixILU0(hypre_CSRMatrix *A);

/* csr_matrix.c */
hypre_CSRMatrix *hypre_CSRMatrixCreate ( HYPRE_Int num_rows, HYPRE_Int num_cols,
                                         HYPRE_Int num_nonzeros );
HYPRE_Int hypre_CSRMatrixDestroy ( hypre_CSRMatrix *matrix );
HYPRE_Int hypre_CSRMatrixInitialize_v2( hypre_CSRMatrix *matrix, HYPRE_Int bigInit,
                                        HYPRE_MemoryLocation memory_location );
HYPRE_Int hypre_CSRMatrixInitialize ( hypre_CSRMatrix *matrix );
HYPRE_Int hypre_CSRMatrixBigInitialize ( hypre_CSRMatrix *matrix );
HYPRE_Int hypre_CSRMatrixBigJtoJ ( hypre_CSRMatrix *matrix );
HYPRE_Int hypre_CSRMatrixJtoBigJ ( hypre_CSRMatrix *matrix );
HYPRE_Int hypre_CSRMatrixSetDataOwner ( hypre_CSRMatrix *matrix, HYPRE_Int owns_data );
HYPRE_Int hypre_CSRMatrixSetPatternOnly( hypre_CSRMatrix *matrix, HYPRE_Int pattern_only );
HYPRE_Int hypre_CSRMatrixSetRownnz ( hypre_CSRMatrix *matrix );
hypre_CSRMatrix *hypre_CSRMatrixRead ( char *file_name );
HYPRE_Int hypre_CSRMatrixPrint ( hypre_CSRMatrix *matrix, const char *file_name );
HYPRE_Int hypre_CSRMatrixPrintIJ( hypre_CSRMatrix *matrix, HYPRE_Int base_i,
                                  HYPRE_Int base_j, char *filename );
HYPRE_Int hypre_CSRMatrixPrintHB ( hypre_CSRMatrix *matrix_input, char *file_name );
HYPRE_Int hypre_CSRMatrixPrintMM( hypre_CSRMatrix *matrix, HYPRE_Int basei, HYPRE_Int basej,
                                  HYPRE_Int trans, const char *file_name );
HYPRE_Int hypre_CSRMatrixCopy ( hypre_CSRMatrix *A, hypre_CSRMatrix *B, HYPRE_Int copy_data );
HYPRE_Int hypre_CSRMatrixMigrate( hypre_CSRMatrix *A, HYPRE_MemoryLocation memory_location );
hypre_CSRMatrix *hypre_CSRMatrixClone ( hypre_CSRMatrix *A, HYPRE_Int copy_data );
hypre_CSRMatrix *hypre_CSRMatrixClone_v2( hypre_CSRMatrix *A, HYPRE_Int copy_data,
                                          HYPRE_MemoryLocation memory_location );
HYPRE_Int hypre_CSRMatrixPermute( hypre_CSRMatrix *A, HYPRE_Int *perm,
                                  HYPRE_Int *rqperm, hypre_CSRMatrix **B_ptr );
hypre_CSRMatrix *hypre_CSRMatrixUnion( hypre_CSRMatrix *A,
                                       hypre_CSRMatrix *B,
                                       HYPRE_BigInt *col_map_offd_A,
                                       HYPRE_BigInt *col_map_offd_B,
                                       HYPRE_BigInt **col_map_offd_C );
HYPRE_Int hypre_CSRMatrixGetLoadBalancedPartitionBegin( hypre_CSRMatrix *A );
HYPRE_Int hypre_CSRMatrixGetLoadBalancedPartitionEnd( hypre_CSRMatrix *A );
HYPRE_Int hypre_CSRMatrixPrefetch( hypre_CSRMatrix *A, HYPRE_MemoryLocation memory_location);
HYPRE_Int hypre_CSRMatrixCheckSetNumNonzeros( hypre_CSRMatrix *matrix );
HYPRE_Int hypre_CSRMatrixResize( hypre_CSRMatrix *matrix, HYPRE_Int new_num_rows,
                                 HYPRE_Int new_num_cols, HYPRE_Int new_num_nonzeros );
HYPRE_Int hypre_CSRMatrixEliminateRowsCols(hypre_CSRMatrix *A, HYPRE_Int nrows, HYPRE_Int *rows);

/* csr_matvec.c */
// y[offset:end] = alpha*A[offset:end,:]*x + beta*b[offset:end]
HYPRE_Int hypre_CSRMatrixMatvecOutOfPlace ( HYPRE_Complex alpha, hypre_CSRMatrix *A,
                                            hypre_Vector *x, HYPRE_Complex beta, hypre_Vector *b, hypre_Vector *y, HYPRE_Int offset );
// y = alpha*A + beta*y
HYPRE_Int hypre_CSRMatrixMatvec ( HYPRE_Complex alpha, hypre_CSRMatrix *A, hypre_Vector *x,
                                  HYPRE_Complex beta, hypre_Vector *y );
HYPRE_Int hypre_CSRMatrixMatvecT ( HYPRE_Complex alpha, hypre_CSRMatrix *A, hypre_Vector *x,
                                   HYPRE_Complex beta, hypre_Vector *y );
HYPRE_Int hypre_CSRMatrixMatvec_FF ( HYPRE_Complex alpha, hypre_CSRMatrix *A, hypre_Vector *x,
                                     HYPRE_Complex beta, hypre_Vector *y, HYPRE_Int *CF_marker_x, HYPRE_Int *CF_marker_y,
                                     HYPRE_Int fpt );

/* csr_matvec_device.c */
HYPRE_Int hypre_CSRMatrixMatvecDevice(HYPRE_Int trans, HYPRE_Complex alpha, hypre_CSRMatrix *A,
                                      hypre_Vector *x, HYPRE_Complex beta, hypre_Vector *b, hypre_Vector *y, HYPRE_Int offset );
HYPRE_Int hypre_CSRMatrixMatvecCusparseNewAPI( HYPRE_Int trans, HYPRE_Complex alpha,
                                               hypre_CSRMatrix *A, hypre_Vector *x, HYPRE_Complex beta, hypre_Vector *y, HYPRE_Int offset );
HYPRE_Int hypre_CSRMatrixMatvecCusparseOldAPI( HYPRE_Int trans, HYPRE_Complex alpha,
                                               hypre_CSRMatrix *A, hypre_Vector *x, HYPRE_Complex beta, hypre_Vector *y, HYPRE_Int offset );
HYPRE_Int hypre_CSRMatrixMatvecCusparse( HYPRE_Int trans, HYPRE_Complex alpha,
                                         hypre_CSRMatrix *A, hypre_Vector *x, HYPRE_Complex beta, hypre_Vector *y, HYPRE_Int offset );
HYPRE_Int hypre_CSRMatrixMatvecOMPOffload (HYPRE_Int trans, HYPRE_Complex alpha, hypre_CSRMatrix *A,
                                           hypre_Vector *x, HYPRE_Complex beta, hypre_Vector *y, HYPRE_Int offset );
HYPRE_Int hypre_CSRMatrixMatvecRocsparse (HYPRE_Int trans, HYPRE_Complex alpha, hypre_CSRMatrix *A,
                                          hypre_Vector *x, HYPRE_Complex beta, hypre_Vector *y, HYPRE_Int offset );
HYPRE_Int hypre_CSRMatrixMatvecOnemklsparse (HYPRE_Int trans, HYPRE_Complex alpha,
                                             hypre_CSRMatrix *A,
                                             hypre_Vector *x, HYPRE_Complex beta, hypre_Vector *y, HYPRE_Int offset );

/* genpart.c */
HYPRE_Int hypre_GeneratePartitioning ( HYPRE_BigInt length, HYPRE_Int num_procs,
                                       HYPRE_BigInt **part_ptr );
HYPRE_Int hypre_GenerateLocalPartitioning ( HYPRE_BigInt length, HYPRE_Int num_procs,
                                            HYPRE_Int myid, HYPRE_BigInt *part );

/* mapped_matrix.c */
hypre_MappedMatrix *hypre_MappedMatrixCreate ( void );
HYPRE_Int hypre_MappedMatrixDestroy ( hypre_MappedMatrix *matrix );
HYPRE_Int hypre_MappedMatrixLimitedDestroy ( hypre_MappedMatrix *matrix );
HYPRE_Int hypre_MappedMatrixInitialize ( hypre_MappedMatrix *matrix );
HYPRE_Int hypre_MappedMatrixAssemble ( hypre_MappedMatrix *matrix );
void hypre_MappedMatrixPrint ( hypre_MappedMatrix *matrix );
HYPRE_Int hypre_MappedMatrixGetColIndex ( hypre_MappedMatrix *matrix, HYPRE_Int j );
void *hypre_MappedMatrixGetMatrix ( hypre_MappedMatrix *matrix );
HYPRE_Int hypre_MappedMatrixSetMatrix ( hypre_MappedMatrix *matrix, void *matrix_data );
HYPRE_Int hypre_MappedMatrixSetColMap ( hypre_MappedMatrix *matrix, HYPRE_Int (*ColMap )(HYPRE_Int,
                                                                                         void *));
HYPRE_Int hypre_MappedMatrixSetMapData ( hypre_MappedMatrix *matrix, void *map_data );

/* multiblock_matrix.c */
hypre_MultiblockMatrix *hypre_MultiblockMatrixCreate ( void );
HYPRE_Int hypre_MultiblockMatrixDestroy ( hypre_MultiblockMatrix *matrix );
HYPRE_Int hypre_MultiblockMatrixLimitedDestroy ( hypre_MultiblockMatrix *matrix );
HYPRE_Int hypre_MultiblockMatrixInitialize ( hypre_MultiblockMatrix *matrix );
HYPRE_Int hypre_MultiblockMatrixAssemble ( hypre_MultiblockMatrix *matrix );
void hypre_MultiblockMatrixPrint ( hypre_MultiblockMatrix *matrix );
HYPRE_Int hypre_MultiblockMatrixSetNumSubmatrices ( hypre_MultiblockMatrix *matrix, HYPRE_Int n );
HYPRE_Int hypre_MultiblockMatrixSetSubmatrixType ( hypre_MultiblockMatrix *matrix, HYPRE_Int j,
                                                   HYPRE_Int type );
HYPRE_Int hypre_MultiblockMatrixSetSubmatrix ( hypre_MultiblockMatrix *matrix, HYPRE_Int j,
                                               void *submatrix );

/* vector.c */
hypre_Vector *hypre_SeqVectorCreate ( HYPRE_Int size );
hypre_Vector *hypre_SeqMultiVectorCreate ( HYPRE_Int size, HYPRE_Int num_vectors );
HYPRE_Int hypre_SeqVectorDestroy ( hypre_Vector *vector );
HYPRE_Int hypre_SeqVectorInitializeShell( hypre_Vector *vector );
HYPRE_Int hypre_SeqVectorSetData( hypre_Vector *vector, HYPRE_Complex *data );
HYPRE_Int hypre_SeqVectorSetOwnsTags( hypre_Vector *vector, HYPRE_Int owns_tags );
HYPRE_Int hypre_SeqVectorSetNumTags( hypre_Vector *vector, HYPRE_Int num_tags );
HYPRE_Int hypre_SeqVectorSetTags( hypre_Vector *vector,
                                  HYPRE_MemoryLocation memory_location,
                                  HYPRE_Int *tags );
HYPRE_Int hypre_SeqVectorSetValuesTagged( hypre_Vector *vector, HYPRE_Complex *values );
HYPRE_Int hypre_SeqVectorInitialize_v2( hypre_Vector *vector,
                                        HYPRE_MemoryLocation memory_location );
HYPRE_Int hypre_SeqVectorInitialize ( hypre_Vector *vector );
HYPRE_Int hypre_SeqVectorSetDataOwner ( hypre_Vector *vector, HYPRE_Int owns_data );
HYPRE_Int hypre_SeqVectorSetSize ( hypre_Vector *vector, HYPRE_Int size );
HYPRE_Int hypre_SeqVectorResize ( hypre_Vector *vector, HYPRE_Int size_in,
                                  HYPRE_Int num_vectors_in );
hypre_Vector *hypre_SeqVectorRead ( char *file_name );
HYPRE_Int hypre_SeqVectorPrint ( hypre_Vector *vector, char *file_name );
HYPRE_Int hypre_SeqVectorSetConstantValues ( hypre_Vector *v, HYPRE_Complex value );
HYPRE_Int hypre_SeqVectorSetConstantValuesHost ( hypre_Vector *v, HYPRE_Complex value );
HYPRE_Int hypre_SeqVectorSetRandomValues ( hypre_Vector *v, HYPRE_Int seed );
HYPRE_Int hypre_SeqVectorCopy ( hypre_Vector *x, hypre_Vector *y );
HYPRE_Int hypre_SeqVectorCopyTags ( hypre_Vector *x, hypre_Vector *y );
HYPRE_Int hypre_SeqVectorStridedCopy( hypre_Vector *x, HYPRE_Int istride, HYPRE_Int ostride,
                                      HYPRE_Int size, HYPRE_Complex *data);
hypre_Vector *hypre_SeqVectorCloneDeep ( hypre_Vector *x );
hypre_Vector *hypre_SeqVectorCloneDeep_v2( hypre_Vector *x, HYPRE_MemoryLocation memory_location );
hypre_Vector *hypre_SeqVectorCloneShallow ( hypre_Vector *x );
HYPRE_Int hypre_SeqVectorMigrate( hypre_Vector *x, HYPRE_MemoryLocation  memory_location );
HYPRE_Int hypre_SeqVectorScale( HYPRE_Complex alpha, hypre_Vector *y );
HYPRE_Int hypre_SeqVectorScaleHost( HYPRE_Complex alpha, hypre_Vector *y );
HYPRE_Int hypre_SeqVectorAxpy ( HYPRE_Complex alpha, hypre_Vector *x, hypre_Vector *y );
HYPRE_Int hypre_SeqVectorAxpyHost ( HYPRE_Complex alpha, hypre_Vector *x, hypre_Vector *y );
HYPRE_Int hypre_SeqVectorAxpyz ( HYPRE_Complex alpha, hypre_Vector *x,
                                 HYPRE_Complex beta, hypre_Vector *y,
                                 hypre_Vector *z );
HYPRE_Real hypre_SeqVectorInnerProd ( hypre_Vector *x, hypre_Vector *y );
HYPRE_Real hypre_SeqVectorInnerProdHost ( hypre_Vector *x, hypre_Vector *y );
HYPRE_Int hypre_SeqVectorMassInnerProd(hypre_Vector *x, hypre_Vector **y, HYPRE_Int k,
                                       HYPRE_Int unroll, HYPRE_Real *result);
HYPRE_Int hypre_SeqVectorMassInnerProd4(hypre_Vector *x, hypre_Vector **y, HYPRE_Int k,
                                        HYPRE_Real *result);
HYPRE_Int hypre_SeqVectorMassInnerProd8(hypre_Vector *x, hypre_Vector **y, HYPRE_Int k,
                                        HYPRE_Real *result);
HYPRE_Int hypre_SeqVectorMassDotpTwo(hypre_Vector *x, hypre_Vector *y, hypre_Vector **z,
                                     HYPRE_Int k, HYPRE_Int unroll,  HYPRE_Real *result_x, HYPRE_Real *result_y);
HYPRE_Int hypre_SeqVectorMassDotpTwo4(hypre_Vector *x, hypre_Vector *y, hypre_Vector **z,
                                      HYPRE_Int k, HYPRE_Real *result_x, HYPRE_Real *result_y);
HYPRE_Int hypre_SeqVectorMassDotpTwo8(hypre_Vector *x, hypre_Vector *y, hypre_Vector **z,
                                      HYPRE_Int k,  HYPRE_Real *result_x, HYPRE_Real *result_y);
HYPRE_Int hypre_SeqVectorMassAxpy(HYPRE_Complex *alpha, hypre_Vector **x, hypre_Vector *y,
                                  HYPRE_Int k, HYPRE_Int unroll);
HYPRE_Int hypre_SeqVectorMassAxpy4(HYPRE_Complex *alpha, hypre_Vector **x, hypre_Vector *y,
                                   HYPRE_Int k);
HYPRE_Int hypre_SeqVectorMassAxpy8(HYPRE_Complex *alpha, hypre_Vector **x, hypre_Vector *y,
                                   HYPRE_Int k);
HYPRE_Int hypre_SeqVectorInnerProdTagged( hypre_Vector *x, hypre_Vector *y, HYPRE_Complex *iprod );
HYPRE_Complex hypre_SeqVectorSumElts ( hypre_Vector *vector );
HYPRE_Complex hypre_SeqVectorSumEltsHost ( hypre_Vector *vector );
HYPRE_Int hypre_SeqVectorPointwiseDivpy( hypre_Vector *x, hypre_Vector *b, hypre_Vector *y );
HYPRE_Int hypre_SeqVectorPointwiseDivpyMarked( hypre_Vector *x, hypre_Vector *b, hypre_Vector *y,
                                               HYPRE_Int *marker, HYPRE_Int marker_val );
HYPRE_Int hypre_SeqVectorPointwiseProduct( hypre_Vector *x, hypre_Vector *y, hypre_Vector **z_ptr );
HYPRE_Int hypre_SeqVectorPointwiseDivision( hypre_Vector *x, hypre_Vector *y,
                                            hypre_Vector **z_ptr );
HYPRE_Int hypre_SeqVectorPointwiseInverse( hypre_Vector *x, hypre_Vector **y_ptr );
//HYPRE_Int hypre_SeqVectorMax( HYPRE_Complex alpha, hypre_Vector *x, HYPRE_Complex beta, hypre_Vector *y );

/* csr_spadd_device.c */
HYPRE_Int hypreDevice_CSRSpAdd(HYPRE_Int ma, HYPRE_Int mb, HYPRE_Int nnzA,
                               HYPRE_Int nnzB, HYPRE_Int *d_ia, HYPRE_Int *d_ja, HYPRE_Complex alpha, HYPRE_Complex *d_aa,
                               HYPRE_Int *d_ja_map, HYPRE_Int *d_ib, HYPRE_Int *d_jb, HYPRE_Complex beta, HYPRE_Complex *d_ab,
                               HYPRE_Int *d_jb_map, HYPRE_Int *d_num_b, HYPRE_Int *nnzC_out, HYPRE_Int **d_ic_out,
                               HYPRE_Int **d_jc_out, HYPRE_Complex **d_ac_out);

/* csr_sptrans_device.c */
HYPRE_Int hypreDevice_CSRSpTrans(HYPRE_Int m, HYPRE_Int n, HYPRE_Int nnzA, HYPRE_Int *d_ia,
                                 HYPRE_Int *d_ja, HYPRE_Complex *d_aa, HYPRE_Int **d_ic_out, HYPRE_Int **d_jc_out,
                                 HYPRE_Complex **d_ac_out, HYPRE_Int want_data);
HYPRE_Int hypreDevice_CSRSpTransCusparse(HYPRE_Int m, HYPRE_Int n, HYPRE_Int nnzA, HYPRE_Int *d_ia,
                                         HYPRE_Int *d_ja, HYPRE_Complex *d_aa, HYPRE_Int **d_ic_out, HYPRE_Int **d_jc_out,
                                         HYPRE_Complex **d_ac_out, HYPRE_Int want_data);
HYPRE_Int hypreDevice_CSRSpTransRocsparse(HYPRE_Int m, HYPRE_Int n, HYPRE_Int nnzA, HYPRE_Int *d_ia,
                                          HYPRE_Int *d_ja, HYPRE_Complex *d_aa, HYPRE_Int **d_ic_out, HYPRE_Int **d_jc_out,
                                          HYPRE_Complex **d_ac_out, HYPRE_Int want_data);
HYPRE_Int hypreDevice_CSRSpTransOnemklsparse(HYPRE_Int m, HYPRE_Int n, HYPRE_Int nnzA,
                                             HYPRE_Int *d_ia, HYPRE_Int *d_ja, HYPRE_Complex *d_aa, HYPRE_Int **d_ic_out, HYPRE_Int **d_jc_out,
                                             HYPRE_Complex **d_ac_out, HYPRE_Int want_data);

/* csr_spgemm_device.c */
HYPRE_Int hypreDevice_CSRSpGemm(hypre_CSRMatrix *A, hypre_CSRMatrix *B, hypre_CSRMatrix **C_ptr);
HYPRE_Int hypreDevice_CSRSpGemmCusparseGenericAPI(HYPRE_Int m, HYPRE_Int k, HYPRE_Int n,
                                                  HYPRE_Int nnzA, HYPRE_Int *d_ia, HYPRE_Int *d_ja, HYPRE_Complex *d_a, HYPRE_Int nnzB,
                                                  HYPRE_Int *d_ib, HYPRE_Int *d_jb, HYPRE_Complex *d_b, HYPRE_Int *nnzC_out, HYPRE_Int **d_ic_out,
                                                  HYPRE_Int **d_jc_out, HYPRE_Complex **d_c_out);

/* csr_spmv_device.c */
HYPRE_Int hypre_CSRMatrixSpMVDevice( HYPRE_Int trans, HYPRE_Complex alpha, hypre_CSRMatrix *A,
                                     hypre_Vector *x,
                                     HYPRE_Complex beta, hypre_Vector *y, HYPRE_Int fill );
HYPRE_Int hypre_CSRMatrixIntSpMVDevice( HYPRE_Int num_rows, HYPRE_Int num_nonzeros,
                                        HYPRE_Int alpha, HYPRE_Int *d_ia, HYPRE_Int *d_ja,
                                        HYPRE_Int *d_a, HYPRE_Int *d_x, HYPRE_Int beta,
                                        HYPRE_Int *d_y );

#if defined(HYPRE_USING_CUSPARSE)  ||\
    defined(HYPRE_USING_ROCSPARSE) ||\
    defined(HYPRE_USING_ONEMKLSPARSE)
hypre_CsrsvData* hypre_CsrsvDataCreate();
HYPRE_Int hypre_CsrsvDataDestroy(hypre_CsrsvData *data);
hypre_GpuMatData* hypre_GpuMatDataCreate();
HYPRE_Int hypre_GPUMatDataSetCSRData(hypre_CSRMatrix *matrix);
HYPRE_Int hypre_GpuMatDataDestroy(hypre_GpuMatData *data);
hypre_GpuMatData* hypre_CSRMatrixGetGPUMatData(hypre_CSRMatrix *matrix);

#define hypre_CSRMatrixGPUMatDescr(matrix)       ( hypre_GpuMatDataMatDescr(hypre_CSRMatrixGetGPUMatData(matrix)) )
#define hypre_CSRMatrixGPUMatInfo(matrix)        ( hypre_GpuMatDataMatInfo (hypre_CSRMatrixGetGPUMatData(matrix)) )
#define hypre_CSRMatrixGPUMatHandle(matrix)      ( hypre_GpuMatDataMatHandle (hypre_CSRMatrixGetGPUMatData(matrix)) )
#define hypre_CSRMatrixGPUMatSpMVBuffer(matrix)  ( hypre_GpuMatDataSpMVBuffer (hypre_CSRMatrixGetGPUMatData(matrix)) )
#endif

HYPRE_Int hypre_CSRMatrixSpMVAnalysisDevice(hypre_CSRMatrix *matrix);

/* vector_device.c */
HYPRE_Int hypre_SeqVectorSetConstantValuesDevice ( hypre_Vector *v, HYPRE_Complex value );
HYPRE_Int hypre_SeqVectorSetValuesTaggedDevice( hypre_Vector *vector, HYPRE_Complex *values );
HYPRE_Int hypre_SeqVectorScaleDevice( HYPRE_Complex alpha, hypre_Vector *y );
HYPRE_Int hypre_SeqVectorAxpyDevice ( HYPRE_Complex alpha, hypre_Vector *x, hypre_Vector *y );
HYPRE_Int hypre_SeqVectorAxpyzDevice ( HYPRE_Complex alpha, hypre_Vector *x,
                                       HYPRE_Complex beta, hypre_Vector *y,
                                       hypre_Vector *z );
HYPRE_Int hypre_SeqVectorPointwiseDivpyDevice( hypre_Vector *x, hypre_Vector *b, hypre_Vector *y,
                                               HYPRE_Int *marker, HYPRE_Int marker_val );
HYPRE_Int hypre_SeqVectorPointwiseProductDevice( hypre_Vector *x, hypre_Vector *y,
                                                 hypre_Vector *z );
HYPRE_Int hypre_SeqVectorPointwiseDivisionDevice( hypre_Vector *x, hypre_Vector *y,
                                                  hypre_Vector *z );
HYPRE_Int hypre_SeqVectorPointwiseInverseDevice( hypre_Vector *x, hypre_Vector *y );
HYPRE_Real hypre_SeqVectorInnerProdDevice ( hypre_Vector *x, hypre_Vector *y );
HYPRE_Complex hypre_SeqVectorSumEltsDevice ( hypre_Vector *vector );
HYPRE_Int hypre_SeqVectorStridedCopyDevice( hypre_Vector *vector,
                                            HYPRE_Int istride, HYPRE_Int ostride,
                                            HYPRE_Int size, HYPRE_Complex *data );
HYPRE_Int hypre_SeqVectorPrefetch(hypre_Vector *x, HYPRE_MemoryLocation memory_location);
